package com.aabte.design.pattern.creational.simplefactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class VideoFactory {

    /**
     * 简单工厂，添加实现类型时，必须修改工厂类，违反了开闭原则
     */
    public Video produce(String type){
        if ("Java".equals(type)) {
            return new JavaVideo();
        } else if ("Python".equals(type)){
            return new PythonVideo();
        }
        return null;
    }

    /**
     * 利用反射解决违反开闭原则
     */
    public Video produce(Class clz){
        Video video = null;

        try {
            video = (Video)Class.forName(clz.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return video;
    }

    private Properties props;

    public void init() {
        if (null != props) {
            return;
        }
        props = new Properties();

        try {
            InputStream in = VideoFactory.class.getClassLoader()
                    .getResourceAsStream("simpleFactory.properties");
            props.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过配置文件来决定实例化哪个实现类
     */
    public <T>T produceExtend(Class<T> clz){
        init();

        T instance = null;

        String type = clz.getName();
        String className = props.getProperty(type);
        try {
            instance = (T)VideoFactory.class.getClassLoader()
                    .loadClass(className).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return instance;
    }


}
